class Setting < ActiveRecord::Base
  class SettingMissing < ActiveRecord::RecordNotFound; end

  validates :key, uniqueness: true

  class << self
    attr_accessor :_cache

    def [](key)
      fetch(key) || (raise SettingMissing.new "Missing key: #{key}.")
    end

    def []=(key, value)
      return down key if value.nil?
      _key = key.to_s
      old = where(key: _key).first
      if old.blank?
        create key: _key, value: value
      else
        old.update value: value
        clear_cache key
      end
    end

    def fetch(key, default = nil)
      where(key: key.to_s).first.try(:value) || default
    end

    def down(key)
      where(key: key.to_s).delete_all
      clear_cache key
    end

    def cache
      @_cache ||= {}
      Proxy.new
    end

    def record(key)
      where(key: key.to_s).first
    end

    def clear_cache(key)
      _cache.delete(key.to_s) || _cache.delete(key) unless _cache.blank?
    end
  end

  class Proxy
    def fetch(key, default = nil)
      if Setting._cache[key].blank?
        result = Setting.fetch key, default
        Setting._cache[key] = result
      end
      Setting._cache[key]
    end
  end
end
